/**
 * 图像处理工具
 * EndoSight-UC 医疗AI系统
 *
 * 提供医疗图像处理、质量检查和优化功能
 */

import fs from 'fs';
import path from 'path';
import { createError } from './errorTypes.js';

// 图像质量评估阈值
const QUALITY_THRESHOLDS = {
  minResolution: { width: 200, height: 200 },      // 最小分辨率
  maxResolution: { width: 4000, height: 4000 },    // 最大分辨率
  minFileSize: 1024,                               // 最小文件大小 (1KB)
  maxFileSize: 20 * 1024 * 1024,                   // 最大文件大小 (20MB)
  maxAspectRatio: 3.0,                             // 最大宽高比
  minAspectRatio: 0.33                             // 最小宽高比
};

// 内窥镜图像特征检测
const ENDOSCOPY_FEATURES = {
  // 典型的内窥镜颜色特征
  colorRanges: {
    redChannel: { min: 50, max: 200 },
    greenChannel: { min: 40, max: 180 },
    blueChannel: { min: 30, max: 150 }
  },
  // 亮度分布特征
  brightnessRanges: {
    min: 30,
    max: 200,
    optimal: { min: 60, max: 160 }
  },
  // 对比度要求
  contrastThreshold: 0.1
};

/**
 * 分析图像基本信息
 * @param {Buffer} imageBuffer - 图像缓冲区
 * @param {string} mimetype - MIME类型
 * @returns {Promise<Object>} 图像信息
 */
export const analyzeImageInfo = async (imageBuffer, mimetype) => {
  try {
    const info = await extractImageMetadata(imageBuffer, mimetype);

    return {
      width: info.width,
      height: info.height,
      channels: info.channels,
      colorSpace: info.colorSpace,
      fileSize: imageBuffer.length,
      format: mimetype,
      aspectRatio: info.width / info.height,
      megapixels: Math.round((info.width * info.height) / 1000000 * 100) / 100
    };
  } catch (error) {
    throw createError.medicalImageValidation(
      `无法分析图像信息: ${error.message}`,
      { mimetype, originalError: error.message }
    );
  }
};

/**
 * 提取图像元数据
 * @param {Buffer} buffer - 图像缓冲区
 * @param {string} mimetype - MIME类型
 * @returns {Promise<Object>} 元数据
 */
const extractImageMetadata = async (buffer, mimetype) => {
  switch (mimetype) {
    case 'image/jpeg':
      return extractJPEGMetadata(buffer);
    case 'image/png':
      return extractPNGMetadata(buffer);
    case 'image/bmp':
      return extractBMPMetadata(buffer);
    default:
      throw new Error(`不支持的图像格式: ${mimetype}`);
  }
};

/**
 * 提取JPEG元数据
 */
const extractJPEGMetadata = (buffer) => {
  let offset = 0;
  let width = 0;
  let height = 0;
  let channels = 3; // 默认RGB

  while (offset < buffer.length - 4) {
    // 查找JPEG标记
    if (buffer[offset] === 0xFF && buffer[offset + 1] === 0xC0) {
      // SOF0标记 (Start of Frame - Baseline DCT)
      height = buffer.readUInt16BE(offset + 5);
      width = buffer.readUInt16BE(offset + 7);
      channels = buffer[offset + 9];
      break;
    }
    offset++;
  }

  if (width === 0 || height === 0) {
    throw new Error('无法解析JPEG尺寸信息');
  }

  return { width, height, channels, colorSpace: 'YCbCr' };
};

/**
 * 提取PNG元数据
 */
const extractPNGMetadata = (buffer) => {
  // PNG文件头验证
  if (buffer.length < 24) {
    throw new Error('PNG文件太小');
  }

  // 跳过PNG文件头 (8字节) 和IHDR块长度 (4字节)
  const offset = 12;

  // 读取IHDR块数据
  const width = buffer.readUInt32BE(offset);
  const height = buffer.readUInt32BE(offset + 4);
  const bitDepth = buffer[offset + 8];
  const colorType = buffer[offset + 9];

  let channels = 3;
  if (colorType === 2) channels = 3;      // RGB
  else if (colorType === 6) channels = 4; // RGBA
  else if (colorType === 0) channels = 1; // Grayscale

  return { width, height, channels, colorSpace: 'RGB' };
};

/**
 * 提取BMP元数据
 */
const extractBMPMetadata = (buffer) => {
  if (buffer.length < 54) {
    throw new Error('BMP文件太小');
  }

  // BMP文件头信息
  const width = buffer.readInt32LE(18);
  const height = Math.abs(buffer.readInt32LE(22)); // 高度可能为负值
  const bitsPerPixel = buffer.readUInt16LE(28);
  const channels = bitsPerPixel / 8;

  return { width, height, channels, colorSpace: 'RGB' };
};

/**
 * 检查图像质量
 * @param {Object} imageInfo - 图像信息
 * @param {Buffer} imageBuffer - 图像缓冲区
 * @returns {Promise<Object>} 质量检查结果
 */
export const checkImageQuality = async (imageInfo, imageBuffer) => {
  const results = {
    passed: true,
    issues: [],
    recommendations: [],
    score: 0
  };

  try {
    // 1. 分辨率检查
    checkResolution(imageInfo, results);

    // 2. 文件大小检查
    checkFileSize(imageInfo, results);

    // 3. 宽高比检查
    checkAspectRatio(imageInfo, results);

    // 4. 内窥镜特征检查
    await checkEndoscopyFeatures(imageBuffer, imageInfo, results);

    // 5. 计算总体质量分数
    calculateQualityScore(results);

    return results;

  } catch (error) {
    throw createError.medicalImageValidation(
      `图像质量检查失败: ${error.message}`,
      { originalError: error.message }
    );
  }
};

/**
 * 检查分辨率
 */
const checkResolution = (imageInfo, results) => {
  const { width, height } = imageInfo;
  const { minResolution, maxResolution } = QUALITY_THRESHOLDS;

  if (width < minResolution.width || height < minResolution.height) {
    results.passed = false;
    results.issues.push({
      type: 'resolution_too_low',
      message: `图像分辨率过低 (${width}x${height})，最小要求为 ${minResolution.width}x${minResolution.height}`,
      severity: 'high'
    });
  }

  if (width > maxResolution.width || height > maxResolution.height) {
    results.issues.push({
      type: 'resolution_too_high',
      message: `图像分辨率过高 (${width}x${height})，可能影响处理性能`,
      severity: 'medium',
      recommendation: '建议调整图像大小以提高处理效率'
    });
  }

  // 检查是否为极端宽高比
  if (width / height > 10 || height / width > 10) {
    results.issues.push({
      type: 'extreme_aspect_ratio',
      message: '图像宽高比过于极端，可能不是标准的医疗图像',
      severity: 'high'
    });
  }
};

/**
 * 检查文件大小
 */
const checkFileSize = (imageInfo, results) => {
  const { fileSize } = imageInfo;
  const { minFileSize, maxFileSize } = QUALITY_THRESHOLDS;

  if (fileSize < minFileSize) {
    results.passed = false;
    results.issues.push({
      type: 'file_too_small',
      message: `文件大小过小 (${Math.round(fileSize / 1024)}KB)，可能不是完整的图像`,
      severity: 'high'
    });
  }

  if (fileSize > maxFileSize) {
    results.issues.push({
      type: 'file_too_large',
      message: `文件大小过大 (${Math.round(fileSize / 1024 / 1024)}MB)，可能影响处理性能`,
      severity: 'medium',
      recommendation: '建议压缩图像以提高处理效率'
    });
  }
};

/**
 * 检查宽高比
 */
const checkAspectRatio = (imageInfo, results) => {
  const { width, height } = imageInfo;
  const { minAspectRatio, maxAspectRatio } = QUALITY_THRESHOLDS;
  const aspectRatio = width / height;

  if (aspectRatio < minAspectRatio || aspectRatio > maxAspectRatio) {
    results.issues.push({
      type: 'aspect_ratio_out_of_range',
      message: `图像宽高比 (${aspectRatio.toFixed(2)}) 超出推荐范围`,
      severity: 'medium',
      recommendation: '建议使用更标准的图像比例'
    });
  }
};

/**
 * 检查内窥镜特征
 */
const checkEndoscopyFeatures = async (imageBuffer, imageInfo, results) => {
  try {
    // 简化的颜色分析
    const colorAnalysis = analyzeColorDistribution(imageBuffer, imageInfo);

    // 检查是否符合内窥镜图像的颜色特征
    checkEndoscopyColorFeatures(colorAnalysis, results);

    // 检查亮度分布
    const brightnessAnalysis = analyzeBrightnessDistribution(imageBuffer, imageInfo);
    checkEndoscopyBrightnessFeatures(brightnessAnalysis, results);

    // 检查对比度
    const contrast = calculateContrast(imageBuffer, imageInfo);
    checkContrastFeatures(contrast, results);

  } catch (error) {
    results.issues.push({
      type: 'feature_analysis_failed',
      message: `图像特征分析失败: ${error.message}`,
      severity: 'low'
    });
  }
};

/**
 * 分析颜色分布
 */
const analyzeColorDistribution = (buffer, imageInfo) => {
  const { width, height, channels } = imageInfo;
  const pixelCount = width * height;

  let redSum = 0, greenSum = 0, blueSum = 0;
  let sampleCount = 0;

  // 采样分析（避免处理所有像素）
  const sampleStep = Math.max(1, Math.floor(pixelCount / 10000)); // 最多采样10000个像素

  // 简化的像素采样（这里需要根据实际图像格式调整）
  for (let i = 0; i < Math.min(buffer.length - 2, pixelCount * 3); i += sampleStep * 3) {
    if (i + 2 < buffer.length) {
      redSum += buffer[i];
      greenSum += buffer[i + 1];
      blueSum += buffer[i + 2];
      sampleCount++;
    }
  }

  if (sampleCount === 0) {
    throw new Error('无法进行颜色分析');
  }

  return {
    averageRed: redSum / sampleCount,
    averageGreen: greenSum / sampleCount,
    averageBlue: blueSum / sampleCount,
    sampleCount
  };
};

/**
 * 检查内窥镜颜色特征
 */
const checkEndoscopyColorFeatures = (colorAnalysis, results) => {
  const { averageRed, averageGreen, averageBlue } = colorAnalysis;
  const ranges = ENDOSCOPY_FEATURES.colorRanges;

  // 检查红色通道
  if (averageRed < ranges.redChannel.min || averageRed > ranges.redChannel.max) {
    results.issues.push({
      type: 'red_channel_out_of_range',
      message: `红色通道平均值 (${Math.round(averageRed)}) 不在典型内窥镜范围内`,
      severity: 'medium'
    });
  }

  // 检查绿色通道
  if (averageGreen < ranges.greenChannel.min || averageGreen > ranges.greenChannel.max) {
    results.issues.push({
      type: 'green_channel_out_of_range',
      message: `绿色通道平均值 (${Math.round(averageGreen)}) 不在典型内窥镜范围内`,
      severity: 'medium'
    });
  }

  // 检查蓝色通道
  if (averageBlue < ranges.blueChannel.min || averageBlue > ranges.blueChannel.max) {
    results.issues.push({
      type: 'blue_channel_out_of_range',
      message: `蓝色通道平均值 (${Math.round(averageBlue)}) 不在典型内窥镜范围内`,
      severity: 'medium'
    });
  }
};

/**
 * 分析亮度分布
 */
const analyzeBrightnessDistribution = (buffer, imageInfo) => {
  const { width, height } = imageInfo;
  const pixelCount = width * height;

  let brightnessSum = 0;
  let sampleCount = 0;

  // 采样分析
  const sampleStep = Math.max(1, Math.floor(pixelCount / 10000));

  for (let i = 0; i < Math.min(buffer.length - 2, pixelCount * 3); i += sampleStep * 3) {
    if (i + 2 < buffer.length) {
      // 计算亮度 (使用标准RGB转亮度公式)
      const brightness = 0.299 * buffer[i] + 0.587 * buffer[i + 1] + 0.114 * buffer[i + 2];
      brightnessSum += brightness;
      sampleCount++;
    }
  }

  if (sampleCount === 0) {
    throw new Error('无法进行亮度分析');
  }

  return {
    averageBrightness: brightnessSum / sampleCount,
    sampleCount
  };
};

/**
 * 检查内窥镜亮度特征
 */
const checkEndoscopyBrightnessFeatures = (brightnessAnalysis, results) => {
  const { averageBrightness } = brightnessAnalysis;
  const ranges = ENDOSCOPY_FEATURES.brightnessRanges;

  if (averageBrightness < ranges.min || averageBrightness > ranges.max) {
    results.passed = false;
    results.issues.push({
      type: 'brightness_out_of_range',
      message: `图像亮度 (${Math.round(averageBrightness)}) 不在可接受范围内`,
      severity: 'high',
      recommendation: '建议调整图像亮度以提高诊断质量'
    });
  }

  if (averageBrightness < ranges.optimal.min || averageBrightness > ranges.optimal.max) {
    results.issues.push({
      type: 'brightness_not_optimal',
      message: `图像亮度 (${Math.round(averageBrightness)}) 不在最佳范围内`,
      severity: 'low',
      recommendation: '建议微调亮度以获得最佳诊断效果'
    });
  }
};

/**
 * 计算对比度
 */
const calculateContrast = (buffer, imageInfo) => {
  const { width, height } = imageInfo;
  const pixelCount = width * height;

  let minBrightness = 255;
  let maxBrightness = 0;

  // 采样计算
  const sampleStep = Math.max(1, Math.floor(pixelCount / 5000));

  for (let i = 0; i < Math.min(buffer.length - 2, pixelCount * 3); i += sampleStep * 3) {
    if (i + 2 < buffer.length) {
      const brightness = 0.299 * buffer[i] + 0.587 * buffer[i + 1] + 0.114 * buffer[i + 2];
      minBrightness = Math.min(minBrightness, brightness);
      maxBrightness = Math.max(maxBrightness, brightness);
    }
  }

  return (maxBrightness - minBrightness) / 255; // 标准化到0-1范围
};

/**
 * 检查对比度特征
 */
const checkContrastFeatures = (contrast, results) => {
  const threshold = ENDOSCOPY_FEATURES.contrastThreshold;

  if (contrast < threshold) {
    results.issues.push({
      type: 'low_contrast',
      message: `图像对比度过低 (${(contrast * 100).toFixed(1)}%)，可能影响诊断`,
      severity: 'medium',
      recommendation: '建议增强图像对比度以提高诊断质量'
    });
  }
};

/**
 * 计算质量分数
 */
const calculateQualityScore = (results) => {
  let score = 100;

  results.issues.forEach(issue => {
    switch (issue.severity) {
      case 'critical':
        score -= 30;
        break;
      case 'high':
        score -= 20;
        break;
      case 'medium':
        score -= 10;
        break;
      case 'low':
        score -= 5;
        break;
    }
  });

  results.score = Math.max(0, score);

  // 根据分数给出总体评估
  if (results.score >= 90) {
    results.overallQuality = 'excellent';
  } else if (results.score >= 80) {
    results.overallQuality = 'good';
  } else if (results.score >= 70) {
    results.overallQuality = 'acceptable';
  } else if (results.score >= 60) {
    results.overallQuality = 'poor';
  } else {
    results.overallQuality = 'unacceptable';
  }
};

/**
 * 生成图像处理建议
 * @param {Object} qualityResults - 质量检查结果
 * @returns {Array} 建议列表
 */
export const generateImageRecommendations = (qualityResults) => {
  const recommendations = [];

  qualityResults.issues.forEach(issue => {
    if (issue.recommendation) {
      recommendations.push({
        type: issue.type,
        priority: issue.severity,
        message: issue.recommendation
      });
    }
  });

  // 基于总体质量分数给出通用建议
  if (qualityResults.score < 70) {
    recommendations.push({
      type: 'general_improvement',
      priority: 'medium',
      message: '建议重新拍摄或选择质量更高的图像以获得更好的AI诊断结果'
    });
  }

  return recommendations;
};

export default {
  analyzeImageInfo,
  checkImageQuality,
  generateImageRecommendations,
  QUALITY_THRESHOLDS,
  ENDOSCOPY_FEATURES
};